package one.stand.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.jmp.autocofiguration.util.OssUtil2;
import com.jmp.base.dto.GoodsPriceRemarkRequest;
import com.jmp.base.dto.GoodsSaveRequest;
import com.jmp.feign.AccountFeign;
import com.jmp.util.GoodsUtils;
import lombok.extern.slf4j.Slf4j;
import one.stand.advice.ResultEnum;
import one.stand.event.UpdateGoodsEvent;
import one.stand.mapper.GoodSpecMapperExt;
import one.stand.mapper.GoodsServiceCrmMapper;
import one.stand.mapper.GoodsTypeRelateMapperExt;
import one.stand.mapper.GoodstypeMapperExt;
import one.stand.model.*;
import one.stand.request.GoodSpecRequest;
import one.stand.request.GoodsRequest;
import one.stand.service.GoodsPhotoBaseService;
import one.stand.service.GoodsService;
import one.stand.service.GoodsTypeService;
import one.stand.util.AssertUtil;
import one.stand.util.MoneyUtil;
import one.stand.util.OneConstant;
import one.stand.util.OneListUtil;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @author Administrator
 */
@Service
@Slf4j
public class GoodsServiceImpl implements GoodsService {
    @Autowired
    private ApplicationContext applicationContext;
    @Autowired
    private AccountFeign accountFeign;

    @Autowired
    private GoodsPhotoBaseService goodsPhotoBaseService;
    @Autowired
    private GoodsTypeService goodsTypeService;

    @Autowired
    private GoodsServiceCrmMapper goodsServiceCrmMapper;
    @Autowired
    private GoodSpecMapperExt goodSpecMapperExt;
    @Autowired
    private GoodsTypeRelateMapperExt goodsTypeRelateMapperExt;
    @Autowired
    private GoodstypeMapperExt goodstypeMapperExt;

    @Override
    @Transactional
    public ResultModel<Boolean> moveGoodsInfo(GoodsRequest request) {
        log.info("商品信息移动：{}", JSON.toJSONString(request));
        if (request == null || request.getGoodsId() == null || request.getType() == null) {
            return ResultModel.checkParamFail();
        }
        // 查询被移动的商品信息
        Goods goods = goodsServiceCrmMapper.selectByPrimaryKey(request.getGoodsId());
        Goods goodsModel = goodsServiceCrmMapper.selectSort(goods.getSort(), request.getType(), request.getCId().intValue());
        if (OneConstant.ONE.equals(request.getType())) {
            AssertUtil.nonNull(goodsModel, "到顶了，无法上移！");
        } else if (OneConstant.TWO.equals(request.getType())) {
            AssertUtil.nonNull(goodsModel, "到底了，无法下移！");
        }

        if (goodsServiceCrmMapper.updateSort(goods.getGoodsId(), goodsModel.getSort()) > 0) {
            goodsServiceCrmMapper.updateSort(goodsModel.getGoodsId(), goods.getSort());

            applicationContext.publishEvent(new UpdateGoodsEvent(null, request.getGoodsId()));

            return ResultModel.success(true);
        }
        return ResultModel.fail();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultModel addGoodsInfo(Goods model, Integer companyId, String specIds, String photos, List<GoodsSaveRequest.Spec> goodSpecRequestList) {
        AssertUtil.nonNull(model.getGoodsName(), ResultEnum.PARAM_CHECK, "商品名称不能为空");
        AssertUtil.nonNull(photos, ResultEnum.PARAM_CHECK, "商品主图不能为空");
        if (model.getIsPayment() != null && model.getIsPayment() == 1) {//1 在线支付
            checkPayConfig(companyId);
        }

        model.setGoodsDetails(OssUtil2.getWebsiteUrlReplace(model.getGoodsDetails()));
        photos = OssUtil2.getWebsiteUrlReplace(photos);

        int r;
        model.setGoodsDetails(GoodsUtils.formatDetail(model.getGoodsDetails()));
        if (model.getGoodsId() != null && model.getGoodsId() > 0) {
            r = goodsServiceCrmMapper.updateByPrimaryKeySelective(model);
        } else {
            AssertUtil.nonNull(model.getGoodstypeId(), ResultEnum.PARAM_CHECK, "分类不能为空");
            AssertUtil.nonNull(goodsTypeService.get(model.getGoodstypeId()), ResultEnum.PARAM_CHECK, "分类不能为空");

            model.setCompanyId(companyId);
            model.setCreateTime(new Date());
            model.setIsDel(0);
            model.setSort(goodsServiceCrmMapper.selectSortMax(companyId) + 1);
            r = goodsServiceCrmMapper.insertSelective(model);
        }
        AssertUtil.isTrue(r == 1, ResultEnum.FAIL);

        goodsPhotoBaseService.save(model.getGoodsId(), photos);

        // 兼容pc端逻辑
        if (StringUtils.isNoneBlank(specIds)) {
            // 删除以前的商品规格
            goodSpecMapperExt.delGoodSpec(model.getGoodsId());
//            // 重新绑定商品规格
            GoodSpecModel goodSpecModel = new GoodSpecModel();
            goodSpecModel.setGoodsId(model.getGoodsId());
            goodSpecModel.setSpecIds(specIds.split(OneConstant.arraySymbol));
            goodSpecModel.setIsDel(0);
            goodSpecMapperExt.updateGoodsId(goodSpecModel);
        } else if (OneListUtil.isEmpty(goodSpecRequestList) && model.getIsPayment() == 1) {
            List<GoodSpec> specs = goodSpecMapperExt.selectSpecs(model.getGoodsId());
            AssertUtil.nonNull(specs, ResultEnum.PARAM_CHECK, "产品规格不能为空");
        }

        //crmapp 规格
        saveSpecs(model.getGoodsId(), goodSpecRequestList);

        // 价格库存更新
        goodsServiceCrmMapper.updateBySpec(model.getGoodsId());
        // 优选更新
        applicationContext.publishEvent(new UpdateGoodsEvent(model.getCompanyId(), model.getGoodsId()));

        return ResultModel.success();
    }

    @Override
    public void save(Goods model, Integer companyId, String photos, List<GoodsSaveRequest.Spec> goodSpecRequestList) {
        AssertUtil.nonNull(model.getGoodsName(), ResultEnum.PARAM_CHECK, "商品名称不能为空");
        AssertUtil.nonNull(photos, ResultEnum.PARAM_CHECK, "商品主图不能为空");

        model.setGoodsDetails(OssUtil2.getWebsiteUrlReplace(model.getGoodsDetails()));
        photos = OssUtil2.getWebsiteUrlReplace(photos);

        int r;
        model.setGoodsDetails(GoodsUtils.formatDetail(model.getGoodsDetails()));

        model.setGoodstypeId(getTypeId(model.getGoodstypeId(), companyId));

        if (model.getGoodsId() != null && model.getGoodsId() > 0) {
            r = goodsServiceCrmMapper.updateByPrimaryKeySelective(model);
        } else {
            model.setCompanyId(companyId);
            model.setCreateTime(new Date());
            model.setIsDel(0);
            model.setSort(goodsServiceCrmMapper.selectSortMax(companyId) + 1);
            r = goodsServiceCrmMapper.insertSelective(model);
        }
        AssertUtil.isTrue(r == 1, ResultEnum.FAIL);

        if (OneListUtil.isEmpty(goodSpecRequestList) && model.getIsPayment() == 1) {
            List<GoodSpec> specs = goodSpecMapperExt.selectSpecs(model.getGoodsId());
            AssertUtil.nonNull(specs, ResultEnum.PARAM_CHECK, "产品规格不能为空");
        }
        saveSpecs2(model.getGoodsId(), goodSpecRequestList);

        goodsPhotoBaseService.save(model.getGoodsId(), photos);

        // 价格库存更新
        goodsServiceCrmMapper.updateBySpec(model.getGoodsId());
        // 优选更新
        applicationContext.publishEvent(new UpdateGoodsEvent(model.getCompanyId(), model.getGoodsId()));
    }

    @Override
    @Transactional
    public ResultModel addGoodSpecInfo(GoodSpecRequest request) {
        log.info("添加商品规格：{}", JSON.toJSONString(request));
        if (request == null) {
            return ResultModel.checkParamFail();
        }
        GoodSpec model = new GoodSpec();
        BeanUtils.copyProperties(request, model);
        int r;
        if (request.getSpecId() == null || request.getSpecId() <= 0) {
            model.setCreateTime(new Date());
            model.setIsDel(0);
            r = goodSpecMapperExt.insertSelective(model);
        } else {
            r = goodSpecMapperExt.updateByPrimaryKeySelective(model);
        }
        if (r > 0) {
            model = goodSpecMapperExt.selectByPrimaryKey(model.getSpecId());
            if (Objects.nonNull(model.getGoodsId())) {
                goodsServiceCrmMapper.updateBySpec(model.getGoodsId());
            }
            applicationContext.publishEvent(new UpdateGoodsEvent(null, model.getGoodsId()));
            return ResultModel.success(model.getSpecId());
        }
        return ResultModel.fail();
    }

    @Override
    @Transactional
    public ResultModel transferGoods(GoodsRequest request) {
        if (request == null) {
            return ResultModel.checkParamFail();
        }
        Goods model = new Goods();
        model.setGoodsId(request.getGoodsId());
        model.setGoodstypeId(request.getGoodstypeId());
        int r = goodsServiceCrmMapper.updateByPrimaryKeySelective(model);
        if (r > 0) {
            applicationContext.publishEvent(new UpdateGoodsEvent(null, request.getGoodsId()));
            return ResultModel.success();
        }
        return ResultModel.fail();
    }

    @Override
    @Transactional
    public ResultModel delGoodsInfo(Integer goodsId) {
        Goods model = new Goods();
        model.setGoodsId(goodsId);
        model.setIsDel(1);
        int r = goodsServiceCrmMapper.updateByPrimaryKeySelective(model);
        if (r > 0) {
            goodSpecMapperExt.delGoodSpec(goodsId);
            applicationContext.publishEvent(new UpdateGoodsEvent(null, goodsId));
            return ResultModel.success();
        }
        return ResultModel.fail();
    }

    @Override
    @Transactional
    public ResultModel delGoodSpecInfo(GoodSpecRequest request) {
        if (request == null) {
            return ResultModel.checkParamFail();
        }
        GoodSpec model = new GoodSpec();
        BeanUtils.copyProperties(request, model);
        model.setIsDel(1);
        int r = goodSpecMapperExt.updateByPrimaryKeySelective(model);
        if (r > 0) {
            GoodSpec goodSpec = goodSpecMapperExt.selectByPrimaryKey(request.getSpecId());
            applicationContext.publishEvent(new UpdateGoodsEvent(null, goodSpec.getGoodsId()));
            return ResultModel.success();
        }
        return ResultModel.fail();
    }

    @Override
    @Transactional
    public ResultModel updateGoods(GoodsRequest request) {
        Goods model = new Goods();
        model.setGoodsId(request.getGoodsId());
        model.setQjAgentTime(request.getQjAgentTime());
        model.setQjOrginId(request.getQjOrginId());
        model.setQjVrUrl(request.getQjVrUrl());
        model.setQjWholesalePrice(request.getQjWholesalePrice().longValue());
        goodsServiceCrmMapper.updateByPrimaryKeySelective(model);
        applicationContext.publishEvent(new UpdateGoodsEvent(null, request.getGoodsId()));
        return ResultModel.success();
    }

    @Override
    @Transactional
    public ResultModel agentGoods(GoodsRequest request) {
//        Integer oldGoodsId = request.getGoodsId();
//        Goods goodsModel = goodsMapperExt.selectByPrimaryKey(request.getGoodsId());
//
//        // 产品分类
//        Integer goodstypeId = goodsTypeService.saveCopy(request.getCId().intValue(), goodsModel.getGoodstypeId());
//        AssertUtil.nonNull(goodstypeId, ResultEnum.FAIL);
//        goodsModel.setGoodstypeId(goodstypeId);
//        // 转移产品
//        goodsModel.setGoodsId(null);
//        goodsModel.setQjOrginId(oldGoodsId);
//        goodsModel.setCompanyId(request.getCId().intValue());
//        goodsModel.setCreateTime(new Date());
//        goodsMapperExt.insertSelective(goodsModel);
//
//        // 规格
//        GoodSpecModel goodSpecModel = new GoodSpecModel();
//        goodSpecModel.setGoodsId(oldGoodsId);
//        List<GoodsSepcListDto> goodSpecModelList = goodSpecMapperExt.getSpec(goodSpecModel);
//        for (GoodsSepcListDto specModel : goodSpecModelList) {
//            Integer oldSpecId = specModel.getSpecId();
//            specModel.setSpecId(null);
//            specModel.setGoodsId(goodsModel.getGoodsId());
//            goodSpecMapperExt.insertSelective(specModel);
//            //
//            goodSpecModel = new GoodSpecModel();
//            goodSpecModel.setSpecId(oldSpecId);
//            List<GoodsSepcListDto> goodSpecModelParentList = goodSpecMapperExt.getSpec(goodSpecModel);
//            for (GoodsSepcListDto model : goodSpecModelParentList) {
//                model.setSpecId(null);
//                model.setGoodsId(goodsModel.getGoodsId());
//                model.setParentId(specModel.getSpecId());
//                goodSpecMapperExt.insertSelective(model);
//            }
//        }
//
//        // 图片
//        List<String> photoPics = goodsMapperExt.getPhotoPics(oldGoodsId);
//        for (String photoPic : photoPics) {
//            GoodsModel photo = new GoodsModel();
//            photo.setGoodsId(goodsModel.getGoodsId());
//            photo.setUrl(photoPic);
//            photo.setCreateTime(new Date());
//            photo.setIsDel(0);
//            goodsMapperExt.insertGoodsPhoto(photo);
//        }
//
//        // 修改代理次数
//        goodsMapperExt.updateGoodsAgentTime(oldGoodsId);
        return ResultModel.success();
    }

    @Override
    @Transactional
    public void mainPush(Integer goodsId, boolean mainPush) {
        if (mainPush) {
            Integer count = goodsServiceCrmMapper.selectCountMainPush(goodsId);
            AssertUtil.isTrue(count < 3, ResultEnum.PARAM_CHECK, "只能设置三个主推商品，请先取消其他商品主推");
        }

        Goods goodsUpdate = new Goods();
        goodsUpdate.setGoodsId(goodsId);
        goodsUpdate.setMainPush(BooleanUtils.toInteger(mainPush));
        goodsServiceCrmMapper.updateByPrimaryKeySelective(goodsUpdate);
    }

    @Override
    public void priceHide(Integer companyId) {
        goodsServiceCrmMapper.updatePriceShow(companyId, 0);
    }

    @Override
    public void priceShow(Integer companyId) {
        goodsServiceCrmMapper.updatePriceShow(companyId, 1);
    }

    @Override
    @Transactional
    public void priceRemark(Integer goodsId, Integer showPrice, Integer isPayment, List<GoodsPriceRemarkRequest.GoodsSpec> specs) {
        AssertUtil.nonNull(goodsId, ResultEnum.PARAM_CHECK);

        if (isPayment != null && isPayment == 1) {//1 在线支付
            Goods model = goodsServiceCrmMapper.selectByPrimaryKey(goodsId);
            checkPayConfig(model.getCompanyId());
        }

        Goods goods = new Goods();
        goods.setGoodsId(goodsId);
        goods.setShowPrice(showPrice);
        goods.setIsPayment(isPayment);
        goodsServiceCrmMapper.updateByPrimaryKeySelective(goods);

        GoodSpec specUpdate = new GoodSpec();
        for (GoodsPriceRemarkRequest.GoodsSpec spec : specs) {
            specUpdate.setSpecId(spec.getSpecId());
            specUpdate.setPriceRemark(spec.getPriceRemark());
            goodSpecMapperExt.updateByPrimaryKeySelective(specUpdate);
        }

        goodsServiceCrmMapper.updateBySpec(goodsId);
    }

    @Override
    @Transactional
    public void updatePlatformType(Integer goodsId, List<Integer> typeIds, Integer popularityLevel) {
        Goods goods = new Goods();
        goods.setGoodsId(goodsId);
        goods.setRightReduction(0);
        goods.setPopularityLevel(Objects.nonNull(popularityLevel) ? popularityLevel : 1);//默认为1
        goodsServiceCrmMapper.updateByPrimaryKeySelective(goods);

        goodsTypeRelateMapperExt.deleteByGoodsId(goodsId);
        if (OneListUtil.isNotEmpty(typeIds)) {
            for (Integer typeId : typeIds) {
                GoodsTypeRelate goodsTypeRelate = new GoodsTypeRelate();
                goodsTypeRelate.setGoodsId(goodsId);
                goodsTypeRelate.setTypeId(typeId);
                goodsTypeRelateMapperExt.insertSelective(goodsTypeRelate);
            }
        }

        applicationContext.publishEvent(new UpdateGoodsEvent(null, goodsId));
    }

    @Override
    @Transactional
    public void deletePlatformType(Integer goodsId) {
        Goods goods = new Goods();
        goods.setGoodsId(goodsId);
        goods.setRightReduction(1);
        goodsServiceCrmMapper.updateByPrimaryKeySelective(goods);

        goodsTypeRelateMapperExt.deleteByGoodsId(goodsId);

        applicationContext.publishEvent(new UpdateGoodsEvent(null, goodsId));
    }

    @Override
    @Transactional
    public void show(Integer id) {
        Goods goodsSelect = new Goods();
        goodsSelect.setGoodsId(id);
        goodsSelect.setIsShow(ISSHOW_SHOW);
        goodsServiceCrmMapper.updateByPrimaryKeySelective(goodsSelect);
    }

    @Override
    @Transactional
    public void hide(Integer id) {
        Goods goodsSelect = new Goods();
        goodsSelect.setGoodsId(id);
        goodsSelect.setIsShow(ISSHOW_HIDE);
        goodsServiceCrmMapper.updateByPrimaryKeySelective(goodsSelect);
    }


    @Override
    @Transactional
    public void updateQjVrUrl(Integer goodsId, String qjVrUrl) {
        Goods goods = new Goods();
        goods.setGoodsId(goodsId);
        goods.setQjVrUrl(qjVrUrl);
        goodsServiceCrmMapper.updateByPrimaryKeySelective(goods);

        applicationContext.publishEvent(new UpdateGoodsEvent(null, goodsId));
    }

    @Override
    @Transactional
    public void updateModel(Integer specId, String modelPicUrl, String modelUrl, String modelZipPath) {
        GoodSpec goodSpec = new GoodSpec();
        goodSpec.setSpecId(specId);
        goodSpec.setModelPicUrl(modelPicUrl);
        goodSpec.setModelUrl(modelUrl);
        goodSpec.setModelZipPath(modelZipPath);
        goodSpecMapperExt.updateByPrimaryKeySelective(goodSpec);

        goodSpec = goodSpecMapperExt.selectByPrimaryKey(specId);
        applicationContext.publishEvent(new UpdateGoodsEvent(null, goodSpec.getGoodsId()));
    }

    private void saveSpecs2(Integer goodsId, List<GoodsSaveRequest.Spec> goodSpecRequestList) {
        goodSpecMapperExt.delGoodSpec(goodsId);
        saveSpecs(goodsId, goodSpecRequestList);
    }

    private void saveSpecs(Integer goodsId, List<GoodsSaveRequest.Spec> goodSpecRequestList) {
        if (OneListUtil.isNotEmpty(goodSpecRequestList)) {

            // 判断是否是更新显示状态
            // 重新维护规格 By Joey
            Date date = new Date();
            for (GoodsSaveRequest.Spec specRequest : goodSpecRequestList) {

                AssertUtil.nonNull(specRequest.getSpecName(), ResultEnum.PARAM_CHECK, "商品规格不能为空");

                GoodSpec goodSpecModel = new GoodSpec();
                goodSpecModel.setGoodsId(goodsId);
                goodSpecModel.setSpecName(specRequest.getSpecName());
                goodSpecModel.setParentId(0);
                if (specRequest.getSpecId() == null) {
                    goodSpecModel.setIsDel(0);
                    goodSpecModel.setCreateTime(date);
                    goodSpecMapperExt.insertSelective(goodSpecModel);
                } else {
                    goodSpecModel.setSpecId(specRequest.getSpecId());
                    goodSpecModel.setUtime(date);
                    goodSpecMapperExt.updateByPrimaryKeySelective(goodSpecModel);
                }

                List<GoodsSaveRequest.Spec> specModelList = specRequest.getGoodSpecModelList();
                for (GoodsSaveRequest.Spec specReq : specModelList) {

                    AssertUtil.nonNull(specReq.getSpecAttribute(), ResultEnum.PARAM_CHECK, "商品规格不能为空");
                    AssertUtil.nonNull(specReq.getSpecNum(), ResultEnum.PARAM_CHECK, "商品规格数量不能为空");
                    AssertUtil.nonNull(specReq.getPrice(), ResultEnum.PARAM_CHECK, "商品规格价格不能为空");

                    GoodSpec specModel = new GoodSpec();
                    specModel.setGoodsId(goodsId);
                    specModel.setSpecName(goodSpecModel.getSpecName());
                    specModel.setSpecNum(specReq.getSpecNum());
                    specModel.setPrice(MoneyUtil.getMoneyInt(specReq.getPrice()));
                    specModel.setSpecAttribute(specReq.getSpecAttribute());
                    specModel.setParentId(goodSpecModel.getSpecId());

                    AssertUtil.nonNull(specModel.getParentId(), ResultEnum.PARAM_CHECK, "商品父规格不能为空");

                    if (specReq.getSpecId() == null) {
                        specModel.setIsDel(0);
                        specModel.setCreateTime(date);
                        goodSpecMapperExt.insertSelective(specModel);
                    } else {
                        specModel.setSpecId(specReq.getSpecId());
                        specModel.setUtime(date);
                        goodSpecMapperExt.updateByPrimaryKeySelective(specModel);
                    }
                }
            }
        }
    }

    private void checkPayConfig(Integer companyId) {
//        AccountCompanyIdRequest accountCompanyIdRequest = AccountCompanyIdRequest.builder()
//                .companyId(companyId)
//                .loginEnum(LoginEnum.WX_PAY)
//                .build();
//        ResultModel<AccountResponse> accountResponseResultModel = accountFeign.getCompanyId(accountCompanyIdRequest);
//        AccountResponse companyAccountModel = accountResponseResultModel.isSuccess() ? accountResponseResultModel.getData() : null;
//        AssertUtil.nonNull(companyAccountModel, "未配置支付参数，不能在线支付");
    }

    private Integer getTypeId(Integer typeId, Integer companyId) {
        if (Objects.nonNull(typeId)) {
            GoodsType goodsType = goodsTypeService.get(typeId);
            if (Objects.nonNull(goodsType) && goodsType.getParentId() > GoodsTypeService.PARENT_ID && goodsType.getCompanyId().equals(companyId)) {
                return typeId;
            }
        }

        PageHelper.startPage(1, 1);
        List<GoodsType> goodsTypes = goodstypeMapperExt.selectChildTypes(companyId);
        if (OneListUtil.isNotEmpty(goodsTypes)) {
            AssertUtil.fail(ResultEnum.PARAM_CHECK, "分类不能为空");
        }

        //default type
        GoodsType goodsType = goodstypeMapperExt.selectByGroupName(companyId, DEFAULT_TYPE_PARENT + GoodsTypeService.SPLIT + DEFAULT_TYPE_CHILD);
        if (Objects.nonNull(goodsType)) {
            return goodsType.getGoodstypeId();
        } else {
            goodsType = goodstypeMapperExt.selectByGroupName(companyId, DEFAULT_TYPE_PARENT);
            Integer parentId;
            if (Objects.nonNull(goodsType)) {
                parentId = goodsType.getGoodstypeId();
            } else {
                parentId = goodsTypeService.save(companyId, DEFAULT_TYPE_PARENT, GoodsTypeService.PARENT_ID, null, 1, null);
            }
            return goodsTypeService.save(companyId, DEFAULT_TYPE_CHILD, parentId, null, 1, null);
        }
    }

    private final String DEFAULT_TYPE_PARENT = "默认";
    private final String DEFAULT_TYPE_CHILD = "默认";
}
